/*  Easy DirectShow
 *  Copyright (c) 2008 Zhenfang Tang <helorlove@gmail.com>
 *
 *	This file is part of EasyDS.
 *
 * 	EasyDS is free software: you can redistribute it and/or modify
 *	it under the terms of the GNU General Public License as published by
 *	the Free Software Foundation, either version 3 of the License, or
 *	(at your option) any later version.
 *
 *	EasyDS is distributed in the hope that it will be useful,
 *	but WITHOUT ANY WARRANTY; without even the implied warranty of
 *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *	GNU General Public License for more details.
 *
 *	You should have received a copy of the GNU General Public License
 *	along with EasyDS.  If not, see <http://www.gnu.org/licenses/>.
 */

#include ".\easydirectshow.h"

#define SAFE_RELEASE(x) { if (x==0) x->Release(); x = 0; }

CEasyDirectShow::CEasyDirectShow(void)
	:mpGB(0)
	,mpGB2(0)
	,mpMC(0)
	,mpBA(0)
	,mpBV(0)
	,mpMS(0)
	,mpMP(0)
	,mpVW(0)
	,mpEvnt(0)

	,mpMux(0)
{
	CoInitialize(NULL);
}

CEasyDirectShow::~CEasyDirectShow(void)
{
	CloseInterface();
	CoUninitialize();
}

//public member function
bool CEasyDirectShow::Open(LPCWSTR apFileName,int aiLen, char acType)
{
	if (acType == EDS_FILE) //file
	{
		OpenFile(apFileName,aiLen);
	}
	else if (acType == EDS_DEVICE_PREVIEW)
	{
	}
	else if (acType == EDS_DEVICE_RECV)
	{
	}
	return false;
}

//private member function
void CEasyDirectShow::CloseInterface()
{
	SAFE_RELEASE(mpEvnt)
	SAFE_RELEASE(mpVW)
	SAFE_RELEASE(mpMP)
	SAFE_RELEASE(mpMS)
	SAFE_RELEASE(mpBV)
	SAFE_RELEASE(mpBA)
	SAFE_RELEASE(mpMC)
	SAFE_RELEASE(mpMux);
	SAFE_RELEASE(mpGB2)
	SAFE_RELEASE(mpGB)
}

bool CEasyDirectShow::OpenFile(LPCWSTR apFileName,int aiLen)
{
	hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, \
		IID_IGraphBuilder,(void **)&mpGB);

	if (FAILED(hr))
	{
		return false;
	}

	hr = mpGB->RenderFile(apFileName, NULL);
	if (FAILED(hr))
	{
		return false;
	}

	mpGB->QueryInterface(IID_IMediaControl, (void **)&mpMC);
	mpGB->QueryInterface(IID_IMediaSeeking, (void **)&mpMS);
	mpGB->QueryInterface(IID_IMediaPosition, (void **)&mpMP);

	mpGB->QueryInterface(IID_IBasicAudio,(void**)&mpBA);
	mpGB->QueryInterface(IID_IBasicVideo,(void**)&mpBV);

	mpGB->QueryInterface(IID_IVideoWindow,(void **)&mpVW);

	mpGB->QueryInterface(IID_IMediaEventEx,(void**)&mpEvnt);

	return true;
}

LRESULT CEasyDirectShow::InitCaptureGraphBuilder(IGraphBuilder **ppGraph, 
											ICaptureGraphBuilder2 **ppBuild)
{
	if (!ppGraph || !ppBuild)
	{
		return E_POINTER;
	}
	IGraphBuilder *pGraph = NULL;
	ICaptureGraphBuilder2 *pBuild = NULL;

	// Create the Capture Graph Builder.
	HRESULT hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL, 
		CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2, (void**)&pGraph);
	if (SUCCEEDED(hr))
	{
		// Create the Filter Graph Manager.
		hr = CoCreateInstance(CLSID_FilterGraph, 0, CLSCTX_INPROC_SERVER,
			IID_IGraphBuilder, (void**)&pGraph);
		if (SUCCEEDED(hr))
		{
			// Initialize the Capture Graph Builder.
			pBuild->SetFiltergraph(pGraph);

			// Return both interface pointers to the caller.
			*ppBuild = pBuild;
			*ppGraph = pGraph; // The caller must release both interfaces.
			return S_OK;
		}
		else
		{
			pBuild->Release();
		}
	}
	return hr; // Failed
}

bool CEasyDirectShow::SetOutputFile(LPCWSTR apFileName,char acSubType,char acEncodeType)
{
	if (mpGB2 == 0)
	{
		hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL, \
			CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2, (void**)&mpGB2);

		if (FAILED(hr))
		{
			return false;
		}
	}

	if (acSubType == EDS_AVI)
	{
		hr = mpGB2->SetOutputFileName(&MEDIASUBTYPE_Avi,apFileName,&mpMux,NULL);
	}
	else if (acSubType == EDS_ASF)
	{
		hr = mpGB2->SetOutputFileName(&MEDIASUBTYPE_Avi,apFileName,&mpMux,NULL);
	}

	if (FAILED(hr))
	{
		return false;
	}

	return true;
}